﻿using OAuth2Authorizer;
using OAuth2AuthorizerDemo.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace OAuth2AuthorizerDemo.Controllers
{
    public class HomeController : Controller
    {
        public List<OAuthProvider> Providers
        {
            get
            {
                var providers = (List<OAuthProvider>)Application()["Providers"];
                if (providers == null)
                {
                    providers = new List<OAuthProvider>();
                    Application()["Providers"] = providers;
                }
                return providers;
            }
            set
            {
                Application()["Providers"] = value;
            }
        }

        private HttpApplicationStateBase Application()
        {
            return this.ControllerContext.HttpContext.Application;
        }

        public ActionResult Index()
        {
            var dropboxProvider = Providers.SingleOrDefault(p => p.Name == "dropbox");
            if (dropboxProvider == null)
            {
                dropboxProvider = new DropBoxProvider("dropbox");
                var dropboxAuthorizer = AuthorizerBuilder.Create(BuiltInAuthorizers.DropBox);
                var urlHelper = new UrlHelper(Request.RequestContext);
                var dropboxRedirectUrl = urlHelper.Action("GetDropBoxAccessCode", "Home", null, "http");
                dropboxProvider.Initialize(dropboxAuthorizer, dropboxRedirectUrl);
                Providers.Add(dropboxProvider);
            }
            var boxProvider = Providers.SingleOrDefault(p => p.Name == "box");
            if (boxProvider == null)
            {
                boxProvider = new BoxProvider("box");
                var boxAuthorizer = AuthorizerBuilder.Create(BuiltInAuthorizers.Box);
                var urlHelper = new UrlHelper(Request.RequestContext);
                var boxRedirectUrl = urlHelper.Action("GetBoxAccessCode", "Home", null, "http");
                boxProvider.Initialize(boxAuthorizer, boxRedirectUrl);
                Providers.Add(boxProvider);
            }
            var wpProvider = Providers.SingleOrDefault(p => p.Name == "wordpress");
            if (wpProvider == null)
            {
                wpProvider = new WordPressProvider("wordpress");
                var wpAuthorizer = AuthorizerBuilder.Create(BuiltInAuthorizers.WordPress);
                var urlHelper = new UrlHelper(Request.RequestContext);
                var wpRedirectUrl = urlHelper.Action("GetWpAccessCode", "Home", null, "http");
                wpProvider.Initialize(wpAuthorizer, wpRedirectUrl);
                Providers.Add(wpProvider);
            }
            var gitProvider = Providers.SingleOrDefault(p => p.Name == "github");
            if (gitProvider == null)
            {
                gitProvider = new GitHubProvider("github");
                var builder = new AuthorizerBuilder();
                builder.BuildAuthorizeUrlTemplate("https://github.com/login/oauth/authorize");
                builder.BuildTokenRequest("https://github.com/login/oauth/access_token");
                builder.BuildResponseType(null,null, "scope");
                var gitAuthorizer = builder.Authorizer;
                var urlHelper = new UrlHelper(Request.RequestContext);
                var gitRedirectUrl = urlHelper.Action("GetGitHubAccessCode", "Home", null, "http");
                gitProvider.Initialize(gitAuthorizer, gitRedirectUrl);
                Providers.Add(gitProvider);
            }
            var stackProvider = Providers.SingleOrDefault(p => p.Name == "stackexchange");
            if (stackProvider == null)
            {
                stackProvider = new StackExchangeProvider("stackexchange");
                var stackAuthorizer = AuthorizerBuilder.Create(BuiltInAuthorizers.StackExchange);
                var urlHelper = new UrlHelper(Request.RequestContext);
                var stackRedirectUrl = urlHelper.Action("GetStackExchangeAccessCode", "Home", null, "http");
                stackProvider.Initialize(stackAuthorizer, stackRedirectUrl);
                Providers.Add(stackProvider);
            }

            var fbProvider = Providers.SingleOrDefault(p => p.Name == "facebook");
            if (fbProvider == null)
            {
                fbProvider = new FacebookProvider("facebook");
                var fbAuthorizer = AuthorizerBuilder.Create(BuiltInAuthorizers.Facebook);
                var urlHelper = new UrlHelper(Request.RequestContext);
                var redirectUrl = urlHelper.Action("GetFacebookAccessCode", "Home", null, "http");
                fbProvider.Initialize(fbAuthorizer, redirectUrl);
                Providers.Add(fbProvider);
            }
            var gProvider = Providers.SingleOrDefault(p => p.Name == "google");
            if (gProvider == null)
            {
                gProvider = new GoogleProvider("google");
                var gAuthorizer = AuthorizerBuilder.Create(BuiltInAuthorizers.Google);
                var urlHelper = new UrlHelper(Request.RequestContext);
                var redirectUrl = urlHelper.Action("GetGoogleAccessCode", "Home", null, "http");
                gProvider.Initialize(gAuthorizer, redirectUrl);
                Providers.Add(gProvider);
            }
            var mProvider = Providers.SingleOrDefault(p => p.Name == "microsoft");
            if (mProvider == null)
            {
                mProvider = new MicrosoftProvider("microsoft");
                var mAuthorizer = AuthorizerBuilder.Create(BuiltInAuthorizers.Microsoft);
                var urlHelper = new UrlHelper(Request.RequestContext);
                // var redirectUrl = urlHelper.Action("GetMicrosoftAccessCode", "Home", null, "http");
                var redirectUrl = "http://localhost.dell.com/OAuth2AuthorizerDemo/Home/GetMicrosoftAccessCode";
                mProvider.Initialize(mAuthorizer, redirectUrl);
                Providers.Add(mProvider);
            }
            return View(Providers);
        }

        public ActionResult GetDropBoxAccessCode(string code, string state)
        {
            var dropboxProvider = Providers.SingleOrDefault(p => p.Name == "dropbox");
            dropboxProvider.GetAccessToken(code);
            return RedirectToAction("Index");
        }

        public ActionResult GetBoxAccessCode(string code, string state)
        {
            var boxProvider = Providers.SingleOrDefault(p => p.Name == "box");
            boxProvider.GetAccessToken(code);
            return RedirectToAction("Index");
        }

        public ActionResult GetWpAccessCode(string code)
        {
            var wpProvider = Providers.SingleOrDefault(p => p.Name == "wordpress");
            wpProvider.GetAccessToken(code);
            return RedirectToAction("Index");
        }

        public ActionResult GetGitHubAccessCode(string code, string state)
        {
            var gitProvider = Providers.SingleOrDefault(p => p.Name == "github");
            gitProvider.GetAccessToken(code);
            return RedirectToAction("Index");
        }

        public ActionResult GetStackExchangeAccessCode(string code, string state)
        {
            var stackProvider = Providers.SingleOrDefault(p => p.Name == "stackexchange");
            stackProvider.GetAccessToken(code);
            return RedirectToAction("Index");
        }

        public ActionResult GetFacebookAccessCode(string code)
        {
            var provider = Providers.SingleOrDefault(p => p.Name == "facebook");
            provider.GetAccessToken(code);
            return RedirectToAction("Index");
        }

        public ActionResult GetGoogleAccessCode(string code)
        {
            var provider = Providers.SingleOrDefault(p => p.Name == "google");
            provider.GetAccessToken(code);
            return RedirectToAction("Index");
        }

        public ActionResult GetMicrosoftAccessCode(string code)
        {
            var provider = Providers.SingleOrDefault(p => p.Name == "microsoft");
            provider.GetAccessToken(code);
            return RedirectToAction("Index");
        }
    }
}
